package com.fingard.dsp.bank.directbank.nnbill01;

import org.apache.commons.codec.binary.Base64;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.balance.*;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.text.AESHelper;
import com.fingard.text.StringHelper;

import javax.xml.bind.JAXBElement;

public class NNBill01Balance extends NNBill01Base implements IBalance {
	public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506)	throws Exception {
		RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
		retAts.writeStart();
		
		try {
			while(p_req7506.readRecord()){
				ActSetItem actItem = getBankConfig().getActSetItem(p_req7506.readedDetail.actNum, "balance");
				
				if (actItem == null) {
					retAts.writeRespCode("-1");
					retAts.writeRespInfo("未找到账号[" + p_req7506.readedDetail.actNum + "]商户配置信息");
					retAts.writeEnd();
					return retAts;
				}
				
				Version version = new Version();
				
				version.setVersion("1");
				version.setService("ma.mbrinfo.balance");
				
				MaMbrinfoRequestHead reqHeader = new MaMbrinfoRequestHead();
				
				reqHeader.setAppId("testAppid");
				reqHeader.setRequestId("testRequestId");
				reqHeader.setVersion(version);
				
				ObjectFactory objFactory = new ObjectFactory();
				
				JAXBElement<String> memberCode = objFactory.createBalanceApiRequestTypeMemberCode(actItem.merchantId);
				JAXBElement<Integer> acctType = objFactory.createBalanceApiRequestTypeAcctType(1);
				String memberAcctID = getBankConfig().getValueAsString("memberAcctCode7506");
				JAXBElement<String> memberAcctCode = objFactory.createBalanceApiRequestTypeMemberAcctCode(memberAcctID);
				JAXBElement<String> merchantMember = objFactory.createBalanceApiRequestTypeMerchantMemberCode(actItem.merchantId);
				
				BalanceApiRequestType apiReqType = new BalanceApiRequestType();
				
				if (!memberAcctID.equals("")) {
					apiReqType.setMemberAcctCode(memberAcctCode);
				} else {
					apiReqType.setMemberCode(memberCode);
					apiReqType.setAcctType(acctType);
				}
				apiReqType.setMerchantMemberCode(merchantMember);
				
				
				/*
				 *  加密数据
				 */
				String originalData = "";	
				
				String key7506 = getBankConfig().getValueAsString("KEY7506");
				if (key7506.length() == 0) {
					key7506 = getBankConfig().getValueAsString("featureCode7506");
				}
				
				if (!memberAcctID.equals("")) {
					originalData = "&memberCode=&acctType=&memberAcctCode=" + memberAcctID + "&merchantMemberCode=" 
							+ actItem.merchantId + "&key=" + key7506;
				} else {
					originalData = "&memberCode=" + actItem.merchantId + "&acctType=1&memberAcctCode=&merchantMemberCode=" 
							+ actItem.merchantId + "&key=" + key7506;
				}
				
				WriteBankLogLn2("原始数据: \n" + originalData + "\n\n");
				
				byte[] originalBytes = originalData.replace("\"", "").getBytes(getCharset());
				byte[] randomBytes = randomKey();
				
				// 签名
				byte[] signBytes = signByRSA(originalBytes, actItem);
				String signData = Base64.encodeBase64String(signBytes);
				
				// 加密
				String encryptData = AESHelper.encodeAES(randomBytes, originalBytes);

				// 数字信封
				byte[] digitalBytes = encryptByPKRSA(randomBytes,actItem);
				String digitalData = Base64.encodeBase64String(digitalBytes);
				
				/**
				 * 请求体
				 * 		-- 加密数据
				 */
				MaSealPkiDataType pkiReqType = new MaSealPkiDataType();
				
				// 原始数据（证书方式没数据）
				pkiReqType.setOriginalData("");
				
				// 报文签名
				pkiReqType.setSignedData(signData);
				
				// 报文加密
				pkiReqType.setEncryptedData(encryptData);
				
				// 报文数字信封
				pkiReqType.setDigitalEnvelope(digitalData);
				
				/**
				 * 请求体
				 */
				BalanceRequestBody reqBody = new BalanceRequestBody();
				
				// 商户信息
				reqBody.setBalanceApiRequestType(apiReqType);
				// 加密数据
				reqBody.setMaSealPkiDataType(pkiReqType);
				
				/**
				 * 请求对象
				 */
				BalanceRequest balReq = new BalanceRequest();
				
				// 请求头
				balReq.setRequestHeader(reqHeader);
				// 请求体
				balReq.setRequestBody(reqBody);
				
				/*
				 * 请求SOAP包数据
				 */
				StringBuilder reqXml = new StringBuilder();
				
				reqXml.append("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
				reqXml.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:bal=\"http://www.99bill.com/schema/ma/mbrinfo/balance\" xmlns:mbr=\"http://www.99bill.com/schema/ma/mbrinfo\" xmlns:com=\"http://www.99bill.com/schema/commons\">");
				reqXml.append("<soapenv:Header/>");
				reqXml.append("<soapenv:Body>");
				reqXml.append("<bal:balance-request>");
				reqXml.append("<bal:request-header>");
				reqXml.append("<mbr:version> ");
				reqXml.append("<com:version>1</com:version>");
				reqXml.append("<com:service>ma.mbrinfo.balance</com:service>");
				reqXml.append("</mbr:version>");
				reqXml.append(" <mbr:requestId>1</mbr:requestId>");
				reqXml.append("<mbr:appId>1</mbr:appId>");
				reqXml.append("</bal:request-header>");
				reqXml.append("<bal:request-body>");
				reqXml.append("<bal:balanceApiRequestType>");
				if (!memberAcctID.equals("")) {
					reqXml.append("<bal:memberAcctCode>" + memberAcctID + "</bal:memberAcctCode>");
				} else {
					reqXml.append("<bal:memberCode>" + actItem.merchantId + "</bal:memberCode>");
					reqXml.append("<bal:acctType>1</bal:accType>");
				}
				reqXml.append("<bal:merchantMemberCode>" + actItem.merchantId + "</bal:merchantMemberCode>");
				reqXml.append("</bal:balanceApiRequestType>");
				reqXml.append("<bal:maSealPkiDataType>");
				reqXml.append("<mbr:signedData>" + signData + "</mbr:signedData>");
				reqXml.append("<mbr:encryptedData>" + encryptData + "</mbr:encryptedData>");
				reqXml.append("<mbr:digitalEnvelope>" + digitalData + "</mbr:digitalEnvelope>");
				reqXml.append("</bal:maSealPkiDataType>");
				reqXml.append("</bal:request-body>");
				reqXml.append("</bal:balance-request>");
				reqXml.append("</soapenv:Body>");
				reqXml.append("</soapenv:Envelope>");
				
				String reqSoap = reqXml.toString();
				
				// 请求报文
				WriteBankLogStep2(reqSoap);
				
				/**
				 * 发送请求SOAP包并获取返回数据
				 */
				
				// 提交地址
				WriteBankLogLn2("提交快钱请求地址: " + bankFront.getUrl("queryBalance"));
				
				BalanceService balService = new BalanceService();
				// 发送请求SOAP包并获取返回数据
				BalanceResponse balResp =  balService.getBalanceSoap11().balance(balReq);
				
				/**
				 * 响应头
				 */
				MaMbrinfoResponseHead respHeader = balResp.getResponseHeader();
				
				// 交易状态码
				String backErrorCode = respHeader.getErrorCode();
				// 交易返回信息
				String backErrorMsg = respHeader.getErrorMsg();
				
				if (backErrorCode.equals("1000")) {
					/**
					 * 响应体
					 */
					BalanceResponseBody respBody = balResp.getResponseBody();
					
					/**
					 * 响应体
					 * 		-- 商户信息
					 */
					BalanceApiResponseType apiRespType = respBody.getBalanceApiResponseType();
					
					// 交易金额
					String totalAmount = StringHelper.amountDivide100(String.valueOf(apiRespType.getAmount()));
					
					/**
					 * 响应体
					 * 		-- 加密数据
					 */
					MaSealPkiDataType pkiRespType = respBody.getMaSealPkiDataType();
					
					// 返回签名
					String backSignData = pkiRespType.getSignedData();
					// 返回数字信封
					String backDigitalData = pkiRespType.getDigitalEnvelope();
					// 返回加密数据
					String backEncryptData = pkiRespType.getEncryptedData();
					
					byte[] backSignBytes = Base64.decodeBase64(backSignData);
					byte[] backencryptBytes = Base64.decodeBase64(backEncryptData);
					byte[] backDigitalBytes = Base64.decodeBase64(backDigitalData);
					
					// 解密数字信封
					byte[] backKey = decryptByPKRSA(backDigitalBytes, actItem);
					// 返回原文
					byte[] backOriginalBytes = AESHelper.decodeAES(backKey, backencryptBytes);
					// 验签结果
					boolean verifyResult = verifyByRSA(backOriginalBytes, backSignBytes, actItem);
					
					// 验签处理
					if (verifyResult == true) {
						// 返回响应数据
						String tmpRetStr = new String(backOriginalBytes, getCharset());
						WriteBankLogLn("请求原数据："+ tmpRetStr);
						String[] retResult = tmpRetStr.replace("\"", "").split("&");
						String amount = "";
						for (int i = 0; i < retResult.length; i++) {
							String[] tmpResp = retResult[i].split("=");
							if (tmpResp[0].equals("amount")) {
								amount = StringHelper.amountDivide100(tmpResp[1]);
							}
						}
						
						if (totalAmount.equals(amount)) {
							// 返回相应数据
							WriteBankLogStep3(tmpRetStr);
							
							RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();
							
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = backErrorMsg;
							tmpRetDetail.actArea = p_req7506.readedDetail.actArea;
							tmpRetDetail.actCur = p_req7506.readedDetail.actCur;
							tmpRetDetail.actNum = p_req7506.readedDetail.actNum;
							tmpRetDetail.currBal = totalAmount;
							tmpRetDetail.availBal = totalAmount;
							tmpRetDetail.frozenBal = "0.00";
							
							retAts.writeRetDetail(tmpRetDetail, false);
						} else {
							retAts.writeRespCode("-1");
							retAts.writeRespInfo("数据已被修改!");
						}
					}else {
						retAts.writeRespCode("-1");
						retAts.writeRespInfo("验签失败!");
					}
					
				} else {
					retAts.writeRespCode("-1");
					retAts.writeRespInfo(backErrorMsg);
				}
			}
		} catch(Exception ex) {
			ex.printStackTrace();
			retAts.writeRespCode("-1");
			retAts.writeRespInfo(ex.getMessage());
			WriteBankLogLn(ex);
		}
		
		retAts.writeEnd();
		return retAts;
	}

	@Override
	public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
		return null;
	}
}
